package java_thinking.unit_17;

/**
 * @Desc:
 * 1.队列是一种特殊的线性容器，它是一种先进先出(FIFO)的数据结构;它只允许在容器的头部进行删除操作，而在表的后端进行插入操作
 *   Queue 实现通常不允许插入 null 元素，尽管某些实现(如 LinkedList)并不禁止插入 null。即使在允许 null 的实现中，也不应该
 *   将 null 插入到 Queue 中，因为 null 也用作 poll 方法的一个特殊返回值，表明队列不包含元素;
 *
 * 2.java Queue中 add/offer，element/peek，remove/poll中的三个方法均为重复的方法，在选择使用时不免有所疑惑，这里简单区别一下：
 *      1、add()和offer()区别:add()和offer()都是向队列中添加一个元素。一些队列有大小限制，因此如果想在一个满的队列中加入一个新项，
 *      调用 add() 方法就会抛出一个 unchecked 异常，而调用 offer() 方法会返回 false。因此就可以在程序中进行有效的判断！
 *      2、poll()和remove()区别：remove() 和 poll() 方法都是从队列中删除第一个元素。如果队列元素为空，调用remove() 的行为与
 *      Collection 接口的版本相似会抛出异常，但是新的 poll() 方法在用空集合调用时只是返回 null。因此新的方法更适合容易出现异
 *      常条件的情况。
 *      3、element() 和 peek() 区别：element() 和 peek() 用于在队列的头部查询元素。与 remove() 方法类似，在队列为空时，
 *      element() 抛出一个异常，而 peek() 返回 null。
 *
 * 3.下面是Java中Queue的一些常用方法：
 *      add         增加一个元索                      如果队列已满，则抛出一个IIIegaISlabEepeplian异常
 *      remove      移除并返回队列头部的元素           如果队列为空，则抛出一个NoSuchElementException异常
 *      element     返回队列头部的元素                如果队列为空，则抛出一个NoSuchElementException异常
 *      offer       添加一个元素并返回true            如果队列已满，则返回false
 *      poll        移除并返问队列头部的元素           如果队列为空，则返回null
 *      peek        返回队列头部的元素                如果队列为空，则返回null
 *      put         添加一个元素                      如果队列满，则阻塞
 *
 * 4.LinkedBlockingQueue的容量是没有上限的(说的不准确，在不指定时容量为Integer.MAX_VALUE，不要然的话在put时怎么会受阻呢)，
 *  但是也可以选择指定其最大容量，它是基于链表的队列，此队列按 FIFO(先进先出)排序元素。
 * 5.ArrayBlockingQueue在构造时需要指定容量， 并可以选择是否需要公平性，如果公平参数被设置true，等待时间最长的线程会优先得到处
 *  理(其实就是通过将ReentrantLock设置为true来 达到这种公平性的：即等待时间最长的线程会先操作)。通常，公平性会使你在性能上付出
 *  代价，只有在的确非常需要的时候再使用它。它是基于数组的阻塞循环队 列，此队列按 FIFO(先进先出)原则对元素进行排序。
 * 6.PriorityBlockingQueue是一个带优先级的 队列，而不是先进先出队列。元素按优先级顺序被移除，该队列也没有上限(看了一下源码，
 *  PriorityBlockingQueue是对 PriorityQueue的再次包装，是基于堆数据结构的，而PriorityQueue是没有容量限制的，与ArrayList一样
 *  ，所以在优先阻塞 队列上put时是不会受阻的。虽然此队列逻辑上是无界的，但是由于资源被耗尽，所以试图执行添加操作可能会导致
 *  OutOfMemoryError)，但是如果队列为空，那么取元素的操作take就会阻塞，所以它的检索操作take是受阻的。另外，往入该队列中的元
 *  素要具有比较能力。
 * 7.DelayQueue(基于PriorityQueue来实现的)是一个存放Delayed 元素的无界阻塞队列，只有在延迟期满时才能从中提取元素。该队列的头部
 *  是延迟期满后保存时间最长的 Delayed 元素。如果延迟都还没有期满，则队列没有头部，并且poll将返回null。当一个元素的
 *  getDelay(TimeUnit.NANOSECONDS) 方法返回一个小于或等于零的值时，则出现期满，poll就以移除这个元素了。此队列不允许使用 null 元素。
 *
 * 8.虽然 LinkedList 没有禁止添加 null，但是一般情况下 Queue 的实现类都不允许添加 null 元素，为啥呢？因为 poll(), peek() 方
 *  法在异常的时候会返回 null，你添加了 null　以后，当获取时不好分辨究竟是否正确返回；
 *
 * 9.Queue 一般都是 FIFO 的，但是也有例外，比如优先队列 priority queue(它的顺序是根据自然排序或者自定义 comparator 的)；
 *  再比如 LIFO 的队列(跟栈一样，后来进去的先出去)。
 *  不论进入、出去的先后顺序是怎样的，使用 remove()，poll() 方法操作的都是 头部 的元素；而插入的位置则不一定是在队尾了，不同的
 *  queue 会有不同的插入逻辑。
 *
 * @author: cww
 * @DateTime: 2019/4/29 10:53
 */

public class QueueTheory {
}
